selenium+PhantomJS 抓取斗鱼房间信息【python】

说明原文连接【点我】

1、环境:selenium+PhantomJS
selenium 可直接安装 : pip install -U selenium
PhantomJS: 官网下载,设置对应bin的路径为环境变量。

2、本文对原作的代码进行了改编,去掉了单元测试部分,因为重点是研究selenium+PhantomJS 抓取异步数据,最后把数据通过mysql导出。

3、代码():

#coding:utf-8
# python 3.5.2


from selenium import webdriver
from bs4 import BeautifulSoup
import pymysql.cursors



class Test(object):
    def __init__(self):
        pass



    def begin_run(self):

        driver = webdriver.PhantomJS()
        driver.get('http://www.douyu.com/directory/all')
        soup = BeautifulSoup(driver.page_source, 'xml')
        while True:
            titles = soup.find_all('h3', {'class': 'ellipsis'})
            # soup.find_all('h3', {class_='ellipsis'})
            nums = soup.find_all('span', {'class': 'dy-num fr'})
            for title, num in zip(titles, nums):
                data = {
                    '房间名': title.get_text(),
                    '观看数量': num.get_text()
                }
                connection = pymysql.connect(host='localhost',
                                     user='root',
                                     password='xxxx',
                                     db='douyu',
                                     charset='utf8'
                                     )

                try:
                    # 创建会话指针
                    with connection.cursor() as cursor:
                        # 创建sql语句
                        sql = 'insert into `douyu1` (`房间名`,`观看数量`) values(%s, %s)'
                        # 执行sql语句
                        cursor.execute(sql, (data['房间名'], data['观看数量']))

                        # 提交
                        connection.commit()
                finally:
                    connection.close()
            if driver.page_source.find('shark-pager-disable-next') != -1:
                break
            elem = driver.find_element_by_class_name('shark-pager-next')
            elem.click()
            soup = BeautifulSoup(driver.page_source, 'xml')

    def start(self):
        Test().begin_run()

if __name__ == "__main__":
    test = Test()
    test.start()

4、其中的坑:
如果默认使用webdriver的“.”查找功能,比如很可能你突然忘记PhantomJS的拼写了,那么查阅回车后,得到的是PhantomJS,注意不是PhantomJS() ,就会导致报错如下:

Error
Traceback (most recent call last):
  File "C:\Users\Administrator\PycharmProjects\untitled\readpdf.py", line 13, in testEle
    driver.get('http://www.douyu.com/directory/all')
TypeError: get() missing 1 required positional argument: 'url'

如果我们分别type他们的信息:

print(type(webdriver.PhantomJS))

print(type(webdriver.PhantomJS()))

得到如下结果:

<class 'type'>

<class 'selenium.webdriver.phantomjs.webdriver.WebDriver'>

也就是说,加了括号,表示得到的是selenium.webdriver.phantomjs.webdriver.WebDriver的具体对象。

5、测试结果:
~天天游戏,天天厨房~ 观看数量比较威猛,

6、原作加入了单元测试的写法,如果有兴趣,可以看下另一篇文章【点我】,对unittest做了有点详细的解释说明。

7、总结:本文学习了 的基本使用方法,另外必须强调的是翻页方面的操作,就斗鱼来说,在总网址下,翻页时在浏览器的地址是不变的,而之前抓取的网站都是跟着翻页变更地址的,形如xxx/1 xxx/2 这样的, 那么必须重点看下源代码的以下几句:

if driver.page_source.find('shark-pager-disable-next') != -1:
    break
elem = driver.find_element_by_class_name('shark-pager-next')
elem.click()
soup = BeautifulSoup(driver.page_source, 'xml')

其中if语句判断 没有下一页了 ,抓取就结束,不然,就通过模拟点击到下一页继续抓取数据。 另外,“下一页”是在名为shark-pager-next的一个类里的,所以那么写,而当到了38页,也就是最后一页后,那个“下一页”的图标就灰色了,通过查看代码,里面是在一个含有shark-pager-disable-next字样的类里